fetcher: Fix another finalization deadlock
authorColin Walters <walters@verbum.org>
Thu, 8 Sep 2016 16:39:42 +0000 (12:39 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Thu, 8 Sep 2016 20:09:07 +0000 (20:09 +0000)
commit82b756783be8c0bcbf7b84d2694dcbca9f58cd0e
tree617536324e206987303cdfa4ea8c5e6a5e0ed763
parent23b4b58d57c7f9f01144a5e59daf26fbe6d5ba4d
fetcher: Fix another finalization deadlock

If the current repo is already up to date (we have no content to
fetch), it's possible for the fetcher to not request any URIs.  So
create and then finalize it quickly.

Finalization involves calling `g_main_loop_quit()` +
`g_thread_wait()`.  However, if `g_main_loop_quit()` is run *before*
`g_main_loop_run()`, we'll deadlock because GMainLoop assumes in
`_run()` to start things.

This is a common trap - ideally, GMainLoop would record if `_quit()`
was called before `_run()` or something, but doing that now would
likely break people who are expecting quit() -> run() to restart.

In general, we've moved in various GLib-consuming apps to an
explicit "main context iteration with termination condition" model;
see `pull_termination_condition()` in the pull code.

This fixes this race condition.

I verified that an assertion in `_finalize` that more than
zero URIs were requested was hit in multiple test cases, and this patch
has survived a while of make check loops.

Closes: https://github.com/ostreedev/ostree/issues/496
Closes: #499
Approved by: jlebon
src/libostree/ostree-fetcher.c